# -*- coding: utf-8 -*-
import scrapy

import re
import logging
import urllib.parse
from copy import copy, deepcopy
from FDC_spider.constants import WX_CLASS_STATUS_DICT, WX_STYLE_STATUS_DICT
from FDC_spider.items import FdcEstateGuidItem, FdcBuildingItem, FdcRoomItem

logger = logging.getLogger(__name__)


class WuxiSpider(scrapy.Spider):
    name = 'wuxi'
    allowed_domains = ['wxhouse.com']
    start_urls = ['http://www.wxhouse.com/listallprice']  # GET/POST  楼盘列表url

    def parse(self, response):
        # 获取区域分组
        tr_li = response.xpath("//a[text()='全部']/../../following-sibling::tr")
        if tr_li:
            for tr in tr_li:
                district_name = tr.xpath(".//a/text()").extract_first()
                district_url = tr.xpath(".//a/@href").extract_first()
                yield response.follow(
                    district_url,
                    callback=self.parse_estate_li,
                    meta=dict(district_name=deepcopy(district_name), page_num=1),
                )
        else:
            logger.error('获取区域信息失败')

    def parse_estate_li(self, response):
        """
        获取楼盘列表
        :param response:
        :return:
        """
        district_name = copy(response.meta['district_name'])
        district_url = response.request.url
        page_num = copy(response.meta['page_num'])
        # 获取楼盘列表分组
        div_li = response.xpath("//div[@class='list_right']")
        if div_li:
            for div in div_li:
                item_eg = FdcEstateGuidItem()
                item_eg['districtName'] = district_name
                item_eg['estateName'] = div.xpath(".//span[@class='loupan_name']/a/text()").extract_first()
                estate_pro_url = div.xpath(".//span[@class='loupan_name']/a/@href").extract_first()
                # 获取楼盘首页
                yield response.follow(
                    estate_pro_url,
                    callback=self.parse_estate_pro,
                    meta={'item_eg': deepcopy(item_eg)},
                )
        else:
            logger.error('{} 第{}页 楼盘列表获取错误'.format(district_name, page_num))

        # 翻页
        try:
            total_page_num_str = response.xpath("//a[text()='末页']/@onclick").extract_first()
            total_page_num = int(self._get_total_page_num(total_page_num_str))
            assert total_page_num
        except:
            logger.error('{} 第{}页 总页数获取错误，{}页之后楼盘列表均获取失败'.format(district_name, page_num, page_num))
        else:
            if page_num < total_page_num:
                page_num += 1
                # 构造下一页请求参数
                data = {
                    'proserh.disCode': self._get_district_code(district_name, district_url),
                    'pager.currentPage': str(page_num),
                }
                yield scrapy.FormRequest(
                    self.start_urls[0],
                    formdata=data,
                    callback=self.parse_estate_li,
                    meta=dict(district_name=deepcopy(district_name), page_num=deepcopy(page_num)),
                )

    def parse_estate_pro(self, response):
        """
        获取楼盘首页
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        item_eg['estateUrl'] = response.xpath("//div[@class='top_lpmenu']//a[2]/@href").extract_first()
        try:
            item_eg['estateUrl'] = urllib.parse.urljoin(response.request.url, item_eg['estateUrl'])
        except:
            logger.error('{}-{} 楼盘详情url获取失败'.format(item_eg['districtName'], item_eg['estateName']))
        else:
            item_eg['estateAddress'] = response.xpath("//strong[contains(text(),'项目地址')]/../text()").extract()
            item_eg['estateAddress'] = self._deal_estate_address(item_eg['estateAddress'])
            yield scrapy.Request(
                item_eg['estateUrl'],
                callback=self.parse_estate_detail,
                meta={'item_eg': deepcopy(item_eg)},
            )

    def parse_estate_detail(self, response):
        """
        获取楼盘详情
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        item_eg['recordName'] = response.xpath("//span[@class='lpbeianame']//text()").extract_first()
        item_eg['recordName'] = self._deal_record_name(item_eg['recordName'])
        item_eg['estateLandPlots'] = response.xpath(
            "//li[contains(text(),'项目地块')]/following-sibling::li[1]/a/text()").extract_first()
        item_eg['mainArea'] = response.xpath(
            "//li[contains(text(),'主力在售')]/following-sibling::li[1]/text()").extract_first()
        item_eg['mainArea'] = response.xpath(
            "//li[contains(text(),'主力在售')]/following-sibling::li[1]/text()").extract_first()
        item_eg['buildingCategory'] = response.xpath(
            "//li[contains(text(),'房屋类型')]/following-sibling::li[1]/text()").extract_first()
        item_eg['handoverDate'] = response.xpath(
            "//li[contains(text(),'交付时间')]/following-sibling::li[1]/text()").extract_first()
        item_eg['openingDate'] = response.xpath(
            "//li[contains(text(),'开盘时间')]/following-sibling::li[1]/text()").extract_first()
        item_eg['parkingSpacesNum'] = response.xpath(
            "//li[contains(text(),'停车位')]/following-sibling::li[1]//text()").extract_first()
        item_eg['totalRoomNo'] = response.xpath(
            "//li[contains(text(),'项目总套数')]/following-sibling::li[1]//text()").extract_first()
        item_eg['floorAreaRatio'] = response.xpath(
            "//li[contains(text(),'容积率')]/following-sibling::li[1]//text()").extract_first()
        item_eg['greeningRate'] = response.xpath(
            "//li[contains(text(),'绿化率')]/following-sibling::li[1]//text()").extract_first()
        item_eg['propertyManagementFee'] = response.xpath(
            "//li[contains(text(),'物管费用')]/following-sibling::li[1]//text()").extract_first()
        item_eg['propertyCompany'] = response.xpath(
            "//li[contains(text(),'物管公司')]/following-sibling::li[1]//text()").extract_first()
        item_eg['enterpriseName'] = response.xpath(
            "//li[contains(text(),'项目公司')]/following-sibling::li[1]//text()").extract_first()
        item_eg['estateIntroduction'] = response.xpath(
            "//p[contains(text(),'楼盘介绍')]/following-sibling::div//text()").extract()
        item_eg['estateIntroduction'] = self._deal_estate_introduction(item_eg['estateIntroduction'])
        item_eg = self._deal_item_eg(item_eg)

        # 获取房号列表
        try:
            # 房号列表url
            bd_li_url = response.xpath("//div[@class='top_lpmenu']//a[8]/@href").extract_first()
            assert bd_li_url
        except:
            logger.warning('{}-{} 楼栋列表url获取失败'.format(item_eg['districtName'], item_eg['estateName']))
        else:
            yield response.follow(
                bd_li_url,
                callback=self.parse_building_li,
                meta={'item_eg': deepcopy(item_eg)},
            )

    def parse_building_li(self, response):
        """
        获取楼栋列表(许可证）
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        # 获取预售许可证分组
        li_list = response.xpath("//li[@class='yszbg']")
        if li_list:
            for li in li_list:
                eg_permit_str = li.xpath(".//text()").extract_first()
                item_eg['preSalePermit'] = self._deal_presale_permit(eg_permit_str)
                yield item_eg
        else:
            logger.warning(
                '{} {}-{} 无法获取预售许可证信息'.format(response.request.url, item_eg['districtName'], item_eg['estateName']))
            item_eg['preSalePermit'] = None
            yield item_eg

        # 获取楼栋分组
        a_li = response.xpath("//li[contains(@class,'yszld')]/..")
        if a_li:
            for a in a_li:
                item_bd = FdcBuildingItem()
                item_bd['districtName'] = item_eg['districtName']
                item_bd['estateName'] = item_eg['estateName']
                item_bd['blockName'] = a.xpath(".//text()").extract_first()
                item_bd['buildingId'] = a.xpath("./li/@id").extract_first()
                bd_permit_str = a.xpath("./preceding-sibling::li[1]/text()").extract_first()
                item_bd['preSalePermit'] = self._deal_presale_permit(bd_permit_str)
                yield item_bd

                # 获取房号列表
                try:
                    rm_li_url = a.xpath(".//@href").extract_first()
                    rm_li_url = urllib.parse.urljoin(response.request.url, rm_li_url)
                except:
                    logger.error('{}-{}-{}-{} 房号列表url获取失败'.format(item_bd['districtName'], item_bd['estateName'],
                                                                  item_bd['preSalePermit'], item_bd['estateName'], ))
                else:
                    yield scrapy.Request(
                        rm_li_url,
                        callback=self.parse_room_li,
                        meta=dict(item_bd=deepcopy(item_bd), ),
                    )
        else:
            logger.warning(
                '{} {}-{} 楼栋列表获取为空'.format(response.request.url, item_eg['districtName'], item_eg['estateName']))

    def parse_room_li(self, response):
        """
        获取房号列表
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        # 获取均价
        price_str = response.xpath("//div[contains(text(),'均价')]/span/text()").extract_first()
        unit_price = self._get_unit_price(price_str)
        # 获取单元分组
        table_li = response.xpath("//div[@id='tabtabm31']//td[contains(text(),'单元')]")
        if table_li:
            for table in table_li:
                unit_name = table.xpath("./text()").extract_first()
                # 获取房号分组
                tr_li = table.xpath("./../../following-sibling::table[1]/tr[position()>1]")
                if tr_li:
                    for tr in tr_li:
                        item_rm = FdcRoomItem()
                        item_rm['districtName'] = item_bd['districtName']
                        item_rm['estateName'] = item_bd['estateName']
                        item_rm['blockName'] = item_bd['blockName']
                        item_rm['buildingId'] = item_bd['buildingId']
                        item_rm['preSalePermit'] = item_bd['preSalePermit']
                        item_rm['unitPrice'] = unit_price
                        item_rm['unitName'] = unit_name
                        item_rm['roomNo'] = tr.xpath("./td[1]/text()").extract_first()
                        item_rm['roomArea'] = tr.xpath("./td[2]/text()").extract_first()
                        item_rm['roomFloor'] = tr.xpath("./td[3]/text()").extract_first()
                        # 获取房号销售状态
                        status_class = tr.xpath("./td[4]//td/@class").extract_first()
                        status_style = tr.xpath("./td[4]//td/@style").extract_first()
                        item_rm['saleStatus'] = self._get_sale_status(status_class, status_style)
                        # 获取房号户型
                        structure_url = tr.xpath("./td[5]//a/@href").extract_first()
                        if structure_url:
                            yield response.follow(
                                structure_url,
                                callback=self.parse_room_structure,
                                meta={'item_rm': deepcopy(item_rm)},
                                dont_filter=True,
                            )
                        else:
                            item_rm['roomStructure'] = None
                            yield item_rm
                else:
                    logger.warning('{} {}-{}-{}-{} 房号列表获取为空'.format(response.request.url, item_bd['districtName'],
                                                                    item_bd['estateName'], item_bd['blockName'],
                                                                    unit_name))
        else:
            logger.warning(
                '{} {}-{}-{} 单元列表获取为空'.format(response.request.url, item_bd['districtName'], item_bd['estateName'],
                                              item_bd['blockName']))

    def parse_room_structure(self, response):
        """
        获取房号户型
        :param response:
        :return:
        """
        item_rm = copy(response.meta['item_rm'])
        structure_str = response.xpath("//p[@id='picdesc']/following-sibling::p[2]/text()").extract_first()
        item_rm['roomStructure'] = self._deal_room_structure(structure_str)
        yield item_rm

    @staticmethod
    def _get_district_code(name_str, url_str):
        """
        获取行政区划参数
        :param name_str: <str>
        :param url_str: <str>
        :return: <str>
        """
        district_code_dict = {
            '梁溪区': 'lx',
            '滨湖区': 'bh',
            '惠山区': 'hs',
            '锡山区': 'xs',
            '新吴区': 'xw',
        }
        try:
            code = url_str.split('=')[1]
        except:
            code = district_code_dict.get(name_str)
        return code

    @staticmethod
    def _get_total_page_num(_str):
        """
        获取楼盘列表总页数
        :param _str: <str>
        :return: <str>
        """
        regex = re.compile(r'\d+')
        try:
            ret_li = regex.findall(_str)
            ret = ret_li[0]
        except:
            return
        else:
            return ret

    @staticmethod
    def _deal_estate_address(_li):
        """
        楼盘字典 字段清洗
        :param _li: <li>
        :return: <str> or None
        """
        try:
            ret = ''.join([i.strip() for i in _li if i])
        except:
            return None
        else:
            return ret if ret else None

    @staticmethod
    def _deal_record_name(_str):
        """
        备案名 字段清洗
        :param _str: <str> or None
        :return: <str> or None
        """
        regex = re.compile(r'）|\s')
        try:
            ret = _str.split('：')[1]
            ret = regex.sub('', ret)
        except:
            return
        else:
            return ret

    @staticmethod
    def _deal_estate_introduction(_li):
        """
        楼盘介绍 字段清洗
        :param _li: <li>
        :return: <li> or None
        """
        try:
            ret_li = [i.strip() for i in _li if i.strip()]
            assert len(ret_li) > 3
        except:
            return
        else:
            return ret_li

    @staticmethod
    def _deal_item_eg(_dict):
        """
        楼盘字典 所有字段清洗
        :param _dict: <dict>
        :return: <dict>
        """
        try:
            new_dict = {i[0]: i[1] if i[1] and '未定' not in str(i[1]) else None for i in _dict.items()}
            for i in new_dict.items():
                if not i[1]:
                    _dict[i[0]] = None
            del new_dict
        except:
            return _dict
        else:
            return _dict

    @staticmethod
    def _deal_presale_permit(_str):
        """
        预售许可证 字段清洗
        :param _str: <str> or None
        :return: <str> or None
        """
        regex = re.compile(r'\+')
        try:
            ret = regex.sub('', _str)
        except:
            return
        else:
            return ret

    @staticmethod
    def _get_unit_price(_str):
        """
        获取房号均价
        :param _str: <str> or None
        :return: <str> or None
        """
        regex = re.compile(r'\d+')
        try:
            ret = regex.findall(_str)[0]
        except:
            return
        else:
            return ret

    @staticmethod
    def _get_sale_status(_str1, _str2):
        """
        获取房号销售状态
        :param _str1: <str> or None
        :param _str2: <str> or None
        :return: <str> or None
        """
        try:
            if _str1:
                ret = WX_CLASS_STATUS_DICT.get(_str1, None)
            elif _str2:
                ret = WX_STYLE_STATUS_DICT.get(_str2, None)
            else:
                ret = None
        except:
            return
        else:
            return ret

    @staticmethod
    def _deal_room_structure(_str):
        """
        房号户型 字段清洗
        :param _str: <str> or None
        :return: <str> or None
        """
        regex = re.compile(r'(\d*.*)\s')
        try:
            ret = regex.findall(_str)[0]
        except:
            return
        else:
            return ret


# 2020/5/19 维护升级
'''
import scrapy

import logging
import re
import urllib.parse
from copy import copy, deepcopy
from FDC_spider.items import FdcEstateGuidItem, FdcBuildingItem, FdcRoomItem
from FDC_spider.constants import WX_CLASS_STATUS_DICT, WX_STYLE_STATUS_DICT

logger = logging.getLogger(__name__)


class WuxiSpider(scrapy.Spider):
    name = 'wuxi'
    allowed_domains = ['wxhouse.com']
    start_urls = ['http://www.wxhouse.com/listpros']

    def parse(self, response):
        # 获取区域分组
        district_a_li = response.xpath("//div[@id='tabtabm41']/div[@class='slist_row']/a[position()>1]")
        # 获取销售状态分组
        sale_a_li = response.xpath("//div[contains(text(),'销售状态')]/a[position()>1]")
        if len(district_a_li) and len(sale_a_li):
            for district_a in district_a_li:
                for sale_a in sale_a_li:
                    item_eg = FdcEstateGuidItem()
                    item_eg['districtName'] = district_a.xpath("./text()").extract_first()
                    item_eg['saleStatus'] = sale_a.xpath("./text()").extract_first()
                    # 构造POST请求参数
                    disCode_str = district_a.xpath("./@onclick").extract_first()
                    disCode_li = re.findall(r"[A-Z]+", disCode_str)
                    disCode = disCode_li[0] if len(disCode_li) else None
                    assert disCode
                    status_str = sale_a.xpath("./@onclick").extract_first()
                    status_li = re.findall(r'\d+', status_str)
                    status = status_li[0] if len(status_li) else None
                    assert status
                    data = {
                        'proserh.disCode': disCode,
                        'proserh.status': status,
                        'pager.currentPage': str(1),
                        'proserh.orderr': 'createtime',
                    }
                    yield scrapy.FormRequest(
                        response.request.url,
                        formdata=data,
                        callback=self.parse_estate_li,
                        meta={'item_eg': deepcopy(item_eg)},
                    )
        else:
            logger.error('获取区域信息或者销售状态分组失败')

    def parse_estate_li(self, response):
        """
        获取楼盘列表
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        # 获取楼盘列表分组
        div_li = response.xpath("//div[@class='fyarea']")
        if len(div_li) > 0 and len(div_li) <= 10:
            for div in div_li:
                item_eg['estateName'] = div.xpath("./div[2]/div//span/text()").extract_first()
                item_eg['avgPrice'] = div.xpath("./div[3]/h1/text()").extract_first()
                estate_pro_url = div.xpath("./div[1]/a/@href").extract_first()
                yield response.follow(
                    estate_pro_url,
                    callback=self.parse_estate_pro,
                    meta={'item_eg': deepcopy(item_eg)},
                )

        # 翻页
        try:
            total_page_num_str = response.xpath("//a[text()='末页']/@onclick").extract_first()
            total_page_num_li = re.findall(r'\d+', total_page_num_str)
            total_page_num = total_page_num_li[0] if len(total_page_num_li) else 0
            assert int(total_page_num) >= 0
        except Exception as e:
            logger.error(
                '{}-{}:楼盘总页数获取错误    error_msg:{}'.format(item_eg['districtName'], item_eg['saleStatus'], e))
        else:
            if int(total_page_num):
                next_page_num_str = response.xpath("//a[text()='下一页']/@onclick").extract_first()
                next_page_num_li = re.findall(r'\d+', next_page_num_str)
                next_page_num = next_page_num_li[0] if len(next_page_num_li) else 0
                if int(next_page_num) <= int(total_page_num):
                    # 构造下一页请求参数
                    data_str = response.request.body.decode()
                    data_li = data_str.split('&')
                    data_dict = {i.split('=')[0]: i.split('=')[1] for i in data_li}
                    next_data_dict = data_dict
                    next_data_dict['pager.currentPage'] = str(next_page_num)
                    yield scrapy.FormRequest(
                        response.request.url,
                        formdata=next_data_dict,
                        callback=self.parse_estate_li,
                        meta=dict(item_eg=deepcopy(item_eg)),
                    )

    def parse_estate_pro(self, response):
        """
        获取楼盘首页
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        try:
            propertyType_li = response.xpath("//strong[contains(text(),'物业类型')]/../text()").extract()
            propertyType = ''.join([i.strip() for i in propertyType_li if i])
        except Exception as e:
            logger.warning('{} {}-{}物业类型获取失败  error_msg:{}'.format(response.request.url, item_eg['districtName'],
                                                                   item_eg['estateName'], e))
            item_eg['propertyType'] = None
        else:
            item_eg['propertyType'] = propertyType if propertyType else None

        try:
            estateAddress_li = response.xpath("//strong[contains(text(),'项目地址')]/../text()").extract()
            estateAddress = ''.join([i.strip() for i in estateAddress_li if i])
        except Exception as e:
            logger.warning('{} {}-{}项目地址获取失败  error_msg:{}'.format(response.request.url, item_eg['districtName'],
                                                                   item_eg['estateName'], e))
            item_eg['estateAddress'] = None
        else:
            item_eg['estateAddress'] = estateAddress if estateAddress else None
        item_eg['estateUrl'] = response.xpath("//div[@class='top_lpmenu']//a[2]/@href").extract_first()
        if item_eg['estateUrl']:
            yield response.follow(
                item_eg['estateUrl'],
                callback=self.parse_estate_detail,
                meta={'item_eg': deepcopy(item_eg)},
            )
        else:
            logger.warning('{} {}-{}无法获取楼盘(项目)信息'.format(response.request.url, item_eg['districtName'],
                                                         item_eg['estateName']))
            item_eg['totalRoomNo'] = None
            item_eg['parkingSpacesNum'] = None
            item_eg['floorAreaRatio'] = None
            item_eg['greeningRate'] = None
            item_eg['propertyManagementFee'] = None
            item_eg['propertyCompany'] = None
            item_eg['enterpriseName'] = None
            item_eg['preSalePermit'] = None
            yield item_eg

    def parse_estate_detail(self, response):
        """
        获取楼盘详情
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        item_eg['estateUrl'] = response.request.url
        item_eg['totalRoomNo'] = response.xpath(
            "//li[contains(text(),'项目总套数')]/following-sibling::li[1]//text()").extract_first()
        item_eg['parkingSpacesNum'] = response.xpath(
            "//li[contains(text(),'停车位')]/following-sibling::li[1]//text()").extract_first()
        item_eg['floorAreaRatio'] = response.xpath(
            "//li[contains(text(),'容积率')]/following-sibling::li[1]//text()").extract_first()
        item_eg['greeningRate'] = response.xpath(
            "//li[contains(text(),'绿化率')]/following-sibling::li[1]//text()").extract_first()
        item_eg['propertyManagementFee'] = response.xpath(
            "//li[contains(text(),'物管费用')]/following-sibling::li[1]//text()").extract_first()
        item_eg['propertyCompany'] = response.xpath(
            "//li[contains(text(),'物管公司')]/following-sibling::li[1]//text()").extract_first()
        item_eg['enterpriseName'] = response.xpath(
            "//li[contains(text(),'项目公司')]/following-sibling::li[1]//text()").extract_first()
        # 房号列表url
        bd_li_url = response.xpath("//div[@class='top_lpmenu']//a[8]/@href").extract_first()
        yield response.follow(
            bd_li_url,
            callback=self.parse_building_li,
            meta={'item_eg': deepcopy(item_eg)},
        )

    def parse_building_li(self, response):
        """
        获取楼栋列表(许可证）
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        # 获取预售许可证分组
        li_list = response.xpath("//li[@class='yszbg']")
        if len(li_list):
            for li in li_list:
                preSalePermit = li.xpath(".//text()").extract_first()
                item_eg['preSalePermit'] = re.sub(r'\+', '', preSalePermit)
                yield item_eg
        else:
            logger.info(
                '{} {}-{}：无法获取预售许可证信息'.format(response.request.url, item_eg['districtName'], item_eg['estateName']))
            item_eg['preSalePermit'] = None
            yield item_eg

        # 获取楼栋分组
        a_li = response.xpath("//li[@class='yszld']/..")
        if len(a_li):
            item_bd = FdcBuildingItem()
            item_bd['districtName'] = item_eg['districtName']
            item_bd['estateName'] = item_eg['estateName']
            for a in a_li:
                item_bd['blockName'] = a.xpath(".//text()").extract_first()
                item_bd['buildingId'] = a.xpath("./li/@id").extract_first()
                buildingUrl = a.xpath(".//@href").extract_first()
                item_bd['buildingUrl'] = urllib.parse.urljoin(response.request.url, buildingUrl)
                preSalePermit = a.xpath("./preceding-sibling::li[1]/text()").extract_first()
                item_bd['preSalePermit'] = re.sub(r'\+', '', preSalePermit)
                yield item_bd
                yield scrapy.Request(
                    item_bd['buildingUrl'],
                    callback=self.parse_room_li,
                    meta={'item_bd': deepcopy(item_bd)},
                )
        else:
            logger.info(
                '{} {}-{}：无法获取楼栋信息'.format(response.request.url, item_eg['districtName'], item_eg['estateName']))

    def parse_room_li(self, response):
        """
        获取房号列表
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        # 获取单元分组
        table_li = response.xpath("//div[@id='tabtabm31']/table[contains(@class,'dgray16px6')]")
        if len(table_li):
            for table in table_li:
                item_rm = FdcRoomItem()
                item_rm['districtName'] = item_bd['districtName']
                item_rm['estateName'] = item_bd['estateName']
                item_rm['blockName'] = item_bd['blockName']
                item_rm['buildingId'] = item_bd['buildingId']
                item_rm['preSalePermit'] = item_bd['preSalePermit']
                unitPrice_str = response.xpath("//span[@class='red24px']/text()").extract_first()
                unitPrice_li = re.findall(r'(\d+)', unitPrice_str)
                item_rm['unitPrice'] = unitPrice_li[0] if len(unitPrice_li) else None
                try:
                    unitName_li = table.xpath("./preceding-sibling::table[1]//text()").extract()
                    unitName = ''.join([i.strip() for i in unitName_li if i])
                    item_rm['unitName'] = unitName
                except Exception as e:
                    logger.warning(
                        '{} {}-{}-{}：无法获取单元信息    error_msg:{}'.format(response.request.url, item_rm['districtName'],
                                                                      item_rm['estateName'], item_rm['blockName'], e))
                    item_rm['unitName'] = None

                # 获取当前单元的房号分组
                tr_li = table.xpath("./tr[position()>1]")
                if len(tr_li):
                    for tr in tr_li:
                        item_rm['roomNo'] = tr.xpath("./td[1]/text()").extract_first()
                        item_rm['roomArea'] = tr.xpath("./td[2]/text()").extract_first()
                        item_rm['roomFloor'] = tr.xpath("./td[3]/text()").extract_first()
                        item_rm['roomUrl'] = tr.xpath("./td[5]//a/@href").extract_first()
                        status_class = tr.xpath("./td[4]//td/@class").extract_first()
                        status_style = tr.xpath("./td[4]//td/@style").extract_first()
                        if status_class:
                            item_rm['saleStatus'] = WX_CLASS_STATUS_DICT.get(status_class, None)
                        elif status_style:
                            item_rm['saleStatus'] = WX_STYLE_STATUS_DICT.get(status_style, None)
                        else:
                            logger.warning(
                                '{} {}-{}-{}-{}-{}：无法获取房号销售状态'.format(response.request.url, item_bd['districtName'],
                                                                      item_bd['estateName'], item_bd['blockName'],
                                                                      item_bd['unitName'], item_bd['roomNo']))
                            item_rm['saleStatus'] = None
                        yield response.follow(
                            item_rm['roomUrl'],
                            callback=self.parse_room_detail,
                            meta={'item_rm': deepcopy(item_rm)},
                            dont_filter=True,
                        )
        else:
            logger.info(
                '{} {}-{}-{}：无法获取房号信息'.format(response.request.url, item_bd['districtName'], item_bd['estateName'],
                                              item_bd['blockName']))

    def parse_room_detail(self, response):
        """
        获取房号详情
        :param response:
        :return:
        """
        item_rm = copy(response.meta['item_rm'])
        item_rm['roomUrl'] = response.request.url
        roomStructureName_str = response.xpath("//p[@id='picdesc']/following-sibling::p[1]/text()").extract_first()
        roomStructureName_li = re.findall(r'户型代码：(.+)', roomStructureName_str) if roomStructureName_str else []
        item_rm['roomStructureName'] = roomStructureName_li[0] if len(roomStructureName_li) else None
        roomStructure_str = response.xpath("//p[@id='picdesc']/following-sibling::p[2]/text()").extract_first()
        roomStructure_li = re.findall(r'([\d].*)[\s]', roomStructure_str) if roomStructure_str else []
        item_rm['roomStructure'] = roomStructure_li[0] if len(roomStructure_li) else None
        yield item_rm
'''
